package com.ljf.authority.utils;

import com.ljf.authority.enums.AuthorityBaseApiTabulationMethodEnum;
import com.ljf.authority.enums.AuthorityBaseApiTabulationTemplateEnum;
import com.ljf.common.exception.ServiceException;
import com.ljf.common.utils.EnumUtil;
import com.ljf.common.utils.StringUtil;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 编码生成工具类
 *
 * @author LJF
 * @since 2025-06-21
 */
public class CodeGenerateUtil {

    private CodeGenerateUtil() {

    }

    /**
     * API列表定义编码生成
     *
     * @param url
     * @param method
     * @return
     * @throws ServiceException
     */
    public static String generateApiTabulationCode(String url, String method) throws ServiceException {
        if (StringUtil.isEmpty(url)) {
            throw new ServiceException("参数异常: URL缺失");
        }
        if (StringUtil.isEmpty(method)) {
            throw new ServiceException("参数异常: 方法缺失");
        }
        String code = convertUrl(url);
        return code + "-" + method;
    }

    /**
     * API列表定义编码生成
     *
     * @param tableName
     * @return
     * @throws ServiceException
     */
    public static List<String> generateApiTabulationCode(String url) throws ServiceException {
        if (StringUtil.isEmpty(url)) {
            throw new ServiceException("参数异常: URL缺失");
        }
        Map<Integer, String> methodMap = new HashMap<>();
        for (AuthorityBaseApiTabulationMethodEnum value : AuthorityBaseApiTabulationMethodEnum.values()) {
            methodMap.put(value.getCode(), value.getCodeSign());
        }
        List<String> resultList = new ArrayList<>();
        for (AuthorityBaseApiTabulationTemplateEnum value : AuthorityBaseApiTabulationTemplateEnum.values()) {
            resultList.add(generateApiTabulationCode(String.format(value.getTemplate(), url), methodMap.getOrDefault(value.getMethod(), "")));
        }
        return resultList;
    }

    /**
     * 表名转化为URL
     *
     * @param tableName
     * @return
     */
    public static String convertToUrl(String tableName) {
        if (tableName == null || tableName.trim().isEmpty()) {
            return "/";
        }
        tableName = tableName.trim();
        int count = 0;
        StringBuilder result = new StringBuilder("/");
        for (int i = 0; i < tableName.length(); i++) {
            char c = tableName.charAt(i);
            if (c == '_' && count < 2) {
                // 替换前两个下划线为斜杠
                result.append('/');
                count++;
            } else {
                // 保留其他字符不变
                result.append(c);
            }
        }
        return result.toString();
    }

    /**
     * URL转化
     *
     * @param path
     * @return
     */
    private static String convertUrl(String path) {
        path = path.replaceAll("[{}]", "").trim();
        // 移除开头和结尾的斜杠
        String cleaned = path.replaceAll("^/|/$", "");
        // 将路径分割为部分
        String[] parts = cleaned.split("/");
        // 转换每个部分：处理下划线后的驼峰命名
        for (int i = 0; i < parts.length; i++) {
            parts[i] = convertPart(parts[i]);
        }
        // 枚举处理
        if (path.contains("enum")) {
            String temp = parts[0];
            parts[0] = parts[1];
            parts[1] = temp;
        }
        // 用连字符连接所有部分
        return String.join("-", parts);
    }

    /**
     * 单个单词转化
     *
     * @param part
     * @return
     */
    private static String convertPart(String part) {
        // 如果没有下划线，直接返回原部分
        if (!part.contains("_")) {
            return part;
        }
        StringBuilder result = new StringBuilder();
        String[] words = part.split("_");
        // 第一个单词保持小写
        result.append(words[0]);
        // 后续单词首字母大写
        for (int i = 1; i < words.length; i++) {
            if (!words[i].isEmpty()) {
                result.append(Character.toUpperCase(words[i].charAt(0)));
                if (words[i].length() > 1) {
                    result.append(words[i].substring(1));
                }
            }
        }
        return result.toString();
    }

}
